﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Input.Inking;
using Windows.UI.Input;
using Windows.Devices.Input;
using Windows.UI.Xaml.Shapes;
using Saisie_des_prélèvements.Models;
using Saisie_des_prélèvements.ViewModels;
using Windows.Storage;
using System.Threading.Tasks;
using Saisie_des_prélèvements.Common;



// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237

namespace Saisie_des_prélèvements.Views
{
    /// <summary>
    /// A basic page that provides characteristics common to most applications.
    /// </summary>
    public sealed partial class SignaturePage : Saisie_des_prélèvements.Common.LayoutAwarePage
    {
        InkManager _inkManager = new Windows.UI.Input.Inking.InkManager();
        Point _previousContactPt;
        uint _penID;
        uint _touchID;
        bool _isDone;
        public int CurrentClientTaken = 0;

        public SignaturePage()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            CurrentClientTaken = int.Parse(navigationParameter.ToString());

            using (var db = new SQLite.SQLiteConnection(App.DBPath))
            {
                k_client_taken info = db.Table<k_client_taken>().Where(c => c.client_taken_id == CurrentClientTaken).First();

                txtClientCode.Text = info.client_taken_code;
                txtNoDos.Text = info.client_seq == null ? "" : info.client_seq;

                List<TakenViewModel> takens = (new TakenViewModel()).GetTakenListByClient(CurrentClientTaken);
                SolidColorBrush[] bgRow = new SolidColorBrush[] { 
                    new SolidColorBrush(Windows.UI.Color.FromArgb(255, 255, 255, 255)),
                    new SolidColorBrush(Windows.UI.Color.FromArgb(255, 255, 123, 33)),
                    new SolidColorBrush(Windows.UI.Color.FromArgb(255, 79, 129, 189)),
                    new SolidColorBrush(Windows.UI.Color.FromArgb(255, 155, 187, 89))
                };
                msg m = new msg();
                string[] RowType = new string[] { m.msgNo, m.msgCancel, m.msgNoCancel, m.msgYes };
                int RowLastIndex = grdSummary.RowDefinitions.Count();
                TextBlock lbl = new TextBlock();
                lbl.FontSize = 14.66;
                lbl.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center;
                lbl.Margin = new Thickness(4);

                foreach (TakenViewModel a in takens)
                {
                    StackPanel sp = new StackPanel();
                    sp.Background = bgRow[a.Status];
                    sp.Margin = new Thickness(1);
                    Grid.SetColumn(sp, 0);
                    Grid.SetRow(sp, RowLastIndex);
                    Grid.SetColumnSpan(sp, 2);
                    // Add the label01 cell to the Grid
                    TextBlock lbl01 = new TextBlock();
                    lbl01.Text = a.TakenPointLabel;
                    lbl01.FontSize = lbl.FontSize;
                    lbl01.Margin = lbl.Margin;
                    lbl01.VerticalAlignment = lbl.VerticalAlignment;
                    Grid.SetColumn(lbl01, 0);
                    Grid.SetRow(lbl01, RowLastIndex);

                    // Add the label02 cell to the Grid
                    TextBlock lbl02 = new TextBlock();
                    lbl02.Text = RowType[a.Status];
                    lbl02.FontSize = lbl.FontSize;
                    lbl02.Margin = lbl.Margin;
                    lbl02.VerticalAlignment = lbl.VerticalAlignment;

                    Grid.SetColumn(lbl02, 1);
                    Grid.SetRow(lbl02, RowLastIndex);

                    RowDefinition row = new RowDefinition();
                    row.MaxHeight = 30;
                    row.MinHeight = 30;
                    grdSummary.RowDefinitions.Add(row);
                    grdSummary.Children.Add(sp);
                    grdSummary.Children.Add(lbl01);
                    grdSummary.Children.Add(lbl02);

                    RowLastIndex++;
                }
                
            }
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
        protected override void SaveState(Dictionary<String, Object> pageState)
        {
        }

        private void InkCanvas_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            // Get information about the pointer location.
            PointerPoint pt = e.GetCurrentPoint(InkCanvas);
            _previousContactPt = pt.Position;

            // Accept input only from a pen or mouse with the left button pressed. 
            PointerDeviceType pointerDevType = e.Pointer.PointerDeviceType;
            if (pointerDevType == PointerDeviceType.Pen ||
                    pointerDevType == PointerDeviceType.Touch ||
                    pointerDevType == PointerDeviceType.Mouse &&
                    pt.Properties.IsLeftButtonPressed)
            {
                // Pass the pointer information to the InkManager.
                _inkManager.ProcessPointerDown(pt);
                _penID = pt.PointerId;

                e.Handled = true;
            }

            else if (pointerDevType == PointerDeviceType.Touch)
            {
                // Process touch input
            }
        }

        private void InkCanvas_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.PointerId == _penID || e.Pointer.PointerId == _touchID)
            {
                PointerPoint pt = e.GetCurrentPoint(InkCanvas);

                // Render a red line on the canvas as the pointer moves. 
                // Distance() is an application-defined function that tests
                // whether the pointer has moved far enough to justify 
                // drawing a new line.
                Point currentContactPt = pt.Position;
                //if (Distance(currentContactPt, _previousContactPt) > 2)
                //{
                    Line line = new Line()
                    {
                        X1 = _previousContactPt.X,
                        Y1 = _previousContactPt.Y,
                        X2 = currentContactPt.X,
                        Y2 = currentContactPt.Y,
                        Stroke = new SolidColorBrush(Windows.UI.Colors.Red)
                    };

                    _previousContactPt = currentContactPt;

                    // Draw the line on the canvas by adding the Line object as
                    // a child of the Canvas object.
                    InkCanvas.Children.Add(line);

                    // Pass the pointer information to the InkManager.
                    _inkManager.ProcessPointerUpdate(pt);
                    _isDone = true;
                //}
            }

            else if (e.Pointer.PointerId == _touchID)
            {
                // Process touch input
            }

            e.Handled = true;
        }

        private void InkCanvas_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.PointerId == _penID || e.Pointer.PointerId == _touchID)
            {
                PointerPoint pt = e.GetCurrentPoint(InkCanvas);

                // Pass the pointer information to the InkManager. 
                _inkManager.ProcessPointerUp(pt);
            }

            else if (e.Pointer.PointerId == _touchID)
            {
                // Process touch input
            }

            _touchID = 0;
            _penID = 0;

            // Call an application-defined function to render the ink strokes.
            //RenderAllStrokes();

            e.Handled = true;
        }

        private void InkCanvas_PointerExited(object sender, PointerRoutedEventArgs e)
        {

        }

        private async void Validate_Click(object sender, RoutedEventArgs e)
        {
            if (!_isDone)
            {
                // Create the message dialog and set its content; it will get a default "Close" button since there aren't any other buttons being added
                var messageDialog = new Windows.UI.Popups.MessageDialog(new msg().sign_Fail);

                // Show the message dialog and wait
                await messageDialog.ShowAsync();

                return;
            }
            var db = new SQLite.SQLiteConnection(App.DBPath);
            k_client_taken client = db.Table<k_client_taken>().Where(c => c.client_taken_id == CurrentClientTaken).First();

            client.signature_label = txtSignature.Text;

            var folder = ApplicationData.Current.TemporaryFolder;
            var file = await folder.OpenStreamForReadAsync(await SaveToFileAsync());
            
            BinaryReader br = new BinaryReader(file);
            byte[] data = br.ReadBytes(int.Parse(file.Length.ToString()));
            client.signature = data;

            
            db.Update(client);

            this.Frame.Navigate(typeof(ClientsPage), CurrentClientTaken);

        }

        public async Task<string> SaveToFileAsync()
        {
            var folder = ApplicationData.Current.TemporaryFolder;
            var file = await folder.CreateFileAsync("signature.png", CreationCollisionOption.ReplaceExisting);

            using (Windows.Storage.Streams.IOutputStream ab = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                if (ab != null)
                    await _inkManager.SaveAsync(ab);
            }
            return file.Name;
        }

        private void GoBack(object sender, RoutedEventArgs e)
        {
            this.Frame.Navigate(typeof(ClientsPage));
        }

       
    }
}
